/**
 * @file    WebExternalHandler.cpp
 * @brief   
 * @date    2005-03-15 15:55:23
 * @author  GengYong (gengyong@gmail.com)
 *
 */

#include <cassert>
#include "WebExternalDispatcher.h"

using namespace xessage_private;

WebExternalDispatcher::WebExternalDispatcher(WebWindowImpl * app):m_appImpl(app), m_refCount(1)
{
	return;
}

WebExternalDispatcher::~WebExternalDispatcher()
{
	return;
}

HRESULT STDMETHODCALLTYPE WebExternalDispatcher::QueryInterface(REFIID riid, LPVOID * ppvObject)
{
	if (ppvObject == NULL) return E_POINTER;

	if ((riid == IID_IUnknown) || (riid == IID_IDispatch))
	{
		this->AddRef();
		*ppvObject = this;
	}
	else
	{
		*ppvObject = 0;
		return E_NOINTERFACE;
	}
	return S_OK;
}

ULONG STDMETHODCALLTYPE WebExternalDispatcher::AddRef()
{
	return InterlockedIncrement(&m_refCount);
}

ULONG STDMETHODCALLTYPE WebExternalDispatcher::Release()
{
	LONG result = InterlockedDecrement(&m_refCount);
	assert(result >= 0);
	if (result == 0)
	{
		delete this;
	}
	return (ULONG)(result);
}

HRESULT STDMETHODCALLTYPE WebExternalDispatcher::GetTypeInfoCount(UINT *pctinfo)
{
	return E_NOTIMPL;;
}

HRESULT STDMETHODCALLTYPE WebExternalDispatcher::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
	return E_NOTIMPL;;
}

HRESULT STDMETHODCALLTYPE WebExternalDispatcher::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
	xessage::IExternalDispatcher * dispatcher = m_appImpl->GetExternalDispatcher();
	for (UINT i = 0; i < cNames; i++)
	{
		rgDispId[i] = DISP_E_UNKNOWNNAME;
		if (dispatcher)
		{
			dispatcher->GetIDOfName(_bstr_t(rgszNames[i]), &rgDispId[i]);
		}
	}
	return S_OK;
}


HRESULT STDMETHODCALLTYPE WebExternalDispatcher::Invoke(DISPID dispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
	if(memcmp(&riid, &IID_NULL, sizeof(GUID)) != 0)  return DISP_E_UNKNOWNINTERFACE;

	UINT aerr = 0;
	if (puArgErr == NULL) puArgErr = &aerr;

	xessage::IExternalDispatcher * dispatcher = m_appImpl->GetExternalDispatcher();
	if (dispatcher)
	{
		return dispatcher->Invoke(dispId, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
	}

	return DISP_E_BADCALLEE;
}

